package com.lc.utils;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by lichao on 2017/5/23.
 */
public class ContextRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
    public static Map<String, Object> sigletons = new HashMap<String, Object>();

        @Override
        public void onApplicationEvent(ContextRefreshedEvent event) {
            // 根容器为Spring容器
            if(event.getApplicationContext().getParent()==null){
                sigletons = event.getApplicationContext().getBeansWithAnnotation(Controller.class);
                System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                System.out.println(sigletons);
                annotationInject();
                /*for(Object bean:sigletons.values()){
                    System.err.println(bean==null?"null":bean.getClass().getName());
                }
                System.err.println("=====ContextRefreshedEvent====="+event.getSource().getClass().getName());*/
            }
        }

    /**
     * 通过注解实现注入依赖对象
     */
    private void annotationInject() {
        for (String beanName : sigletons.keySet()) { // 循环所有的Bean对象
            Object bean = sigletons.get(beanName);
            if (bean != null) {
                try {
                    // 查找属性的setter上是否有注解
                    Field[] fields = bean.getClass().getDeclaredFields();
                    for (Field field : fields) { // 循环所有属性
                        int mod = field.getModifiers();
                        if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){
                            continue;
                        }
                        if (field.isAnnotationPresent(Resource.class)) { // 判断Resource注解是否存在
                            Resource resource = field.getAnnotation(Resource.class);
                            Object injectBean = null;
                            String  name = resource.name();
                            if(name==null){
                                name = field.getName();
                            }
                            Object o = MyApplicationContext.getBean(name+".bl");
                            if(o==null){
                                continue;
                            }
                            field.setAccessible(true);
                            field.set(bean,o);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
